import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { RegistUserDto } from './dto/regist-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { LoginUserDto } from './dto/login-user.dto';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose'
//导入userSchema
import { User, UserDocument } from 'src/mongoScheme/user.schema';
//导入subscribeSchema
import { Subscribe, SubscribeDocument } from 'src/mongoScheme/subscribe.schema';
//导入jwt
import { AuthService } from 'src/auth/auth.service';
//导入lodash
import _ from 'lodash'
@Injectable()
export class UserService {
  constructor(
    @InjectModel(User.name) private userModel: Model<UserDocument>,
    @InjectModel(Subscribe.name) private subscribeModel: Model<SubscribeDocument>,
    private authService: AuthService
  ) { }

  /**
   * 
   * 接下来是验证手机号 邮箱 账户是否存在重复
   */

  async findByName(key: string, val: string) {
    //exec的方式是该函数转换成promise的类型  类似与promisefy
    const dbback = await this.userModel.findOne({ [key]: val }).exec()
    return dbback
  }

  async regist(createUserDto: RegistUserDto) {
    try {
      const accountIsExit = await this.findByName('account', createUserDto.account)
      if (accountIsExit) {
        throw new HttpException('账户已存在', HttpStatus.BAD_REQUEST)
      }

      const phoneIsExit = await this.findByName('phone', createUserDto.phone)
      if (phoneIsExit) {
        throw new HttpException('手机号已存在', HttpStatus.BAD_REQUEST)
      }

      const emailIsExit = await this.findByName('email', createUserDto.email)
      if (emailIsExit) {
        throw new HttpException('邮箱已存在', HttpStatus.BAD_REQUEST)
      }

      const registUser = new this.userModel(createUserDto)
      const dbback = await registUser.save()

      if (!dbback) {
        throw new HttpException('注册失败', HttpStatus.BAD_REQUEST)
      } else {
        return '注册成功'
      }

    } catch (err) {
      throw new HttpException(err, HttpStatus.BAD_REQUEST)
    }

  }

  async login(loginUserDto: LoginUserDto) {
    const dbback = await this.userModel.findOne(loginUserDto)
    const token = await this.authService.createJwt(dbback._id.toString())
    return token;
  }

  async getuser(id: string) {
    const dbback = await this.findByName('_id', id)
    return dbback;
  }

  async updateuser(id: string, updateUserDto: UpdateUserDto) {
    try {
      await this.userModel.findByIdAndUpdate(id, updateUserDto)
      return '修改成功';
    } catch {
      return new HttpException('修改失败', HttpStatus.BAD_REQUEST)
    }
  }

  //关注频道
  async addSub(follower: string, following: string) {
    if(follower === following){
      throw new HttpException('不能关注自己啊',HttpStatus.BAD_REQUEST)
    }
    const isexit = await this.subscribeModel.findOne({ follower, following})
    if(isexit){
      throw new HttpException('已经关注过该频道',HttpStatus.BAD_REQUEST)
    }

    let { subscribecount } =await this.userModel.findOne({_id:following})

    await this.updateuser(following,{subscribecount:subscribecount + 1})

    const subModel = new this.subscribeModel({ follower, following })
    const dbback = await (await subModel.save()).populate('following', 'nickname avater subscribecount')
    return _.pick(dbback,['following'])
  }

  //取消关注
  async subtractSub(follower: string, following: string) {
    if(follower === following){
      throw new HttpException('不能取消关注自己啊',HttpStatus.BAD_REQUEST)
    }
    const isexit = await this.subscribeModel.findOne({ follower, following})
    if(!isexit){
      throw new HttpException('还没关注过该频道',HttpStatus.BAD_REQUEST)
    }
    
    await this.subscribeModel.deleteOne({ follower, following })
    let { subscribecount } =await this.userModel.findOne({_id:following})

    await this.updateuser(following,{subscribecount:subscribecount - 1})

    return '取消关注成功'
  }

  async Sublist(follower: string,page:number,pagesize:number){
    
    const skip = (page - 1) * pagesize
    let dbback = await this.subscribeModel.find({follower}).skip(skip).limit(pagesize).populate('following', 'nickname avater subscribecount') as any
    dbback = dbback.map((item)=>{
      return _.pick(item,['following'])
    })
    const total = await this.subscribeModel.countDocuments({follower})
    return {list:dbback,total}
  }


  async Fansget(following: string,page:number,pagesize:number){
    const skip = (page - 1) * pagesize
    let dbback = await this.subscribeModel.find({following}).skip(skip).limit(pagesize).populate('follower', 'nickname avater subscribecount') as any
    dbback = dbback.map((item)=>{
      return _.pick(item,['follower'])
    })
    const total = await this.subscribeModel.countDocuments({following})
    return {list:dbback,total}
  }
}
